#include "test.h"

namespace test
{
void test_map_in_multi_thread()
{

#ifdef USE_THREAD_SAFE_CONTAINERS
#warning USE_THREAD_SAFE_CONTAINERS
    thread_safe::map<std::string, BaseBox> box_map;
#else
#warning NOT USE_THREAD_SAFE_CONTAINERS
    std::map<std::string, BaseBox> box_map;
#endif

    auto add_box = [&]() {
        while (1)
        {
            for (int i = 0; i < 10; i++)
            {
                BaseBox insert_box;
                if (0 == box_map.count(std::to_string(i)))
                {
                    std::this_thread::sleep_for(std::chrono::milliseconds(3));
                    box_map.insert(std::make_pair<std::string, BaseBox>(std::to_string(i), std::move(insert_box)));
                }
                else
                {
                    std::this_thread::sleep_for(std::chrono::milliseconds(3));
                    auto it = box_map.find(std::to_string(i));
                    it->second = insert_box;
                }
            }
            std::this_thread::sleep_for(std::chrono::milliseconds(1));  // 睡眠10毫秒
            std::cout << "add_box" << std::endl;
        }
    };

    auto get_box = [&]() {
        while (1)
        {
            for (int i = 0; i < 10; i++)
            {
                BaseBox insert_box;
                if (0 != box_map.count(std::to_string(i)))
                {
                    auto it = box_map.find(std::to_string(i));
                    insert_box = it->second;
                }
            }
            box_map.clear();
            std::this_thread::sleep_for(std::chrono::milliseconds(1));  // 睡眠10毫秒
            std::cout << "get_box" << std::endl;
        }
    };

    std::thread t_add_box_1(add_box);
    t_add_box_1.detach();

    std::thread t_add_box_2(add_box);
    t_add_box_2.detach();

    std::thread t_add_box_3(add_box);
    t_add_box_3.detach();

    std::thread t_get_box(get_box);
    t_get_box.detach();
}

void test_queue_in_multi_thread()
{

#ifdef USE_THREAD_SAFE_CONTAINERS
#warning USE_THREAD_SAFE_CONTAINERS
    thread_safe::queue<BaseBox> box_queue;
#else
#warning NOT USE_THREAD_SAFE_CONTAINERS
    std::queue<BaseBox> box_queue;
#endif

    auto add_box = [&]() {
        while (1)
        {
            for (int i = 0; i < 10; i++)
            {
                BaseBox box;
                box_queue.push(box);
                std::this_thread::sleep_for(std::chrono::milliseconds(3));
                box_queue.emplace(box);
            }
            std::cout << "add_box" << std::endl;
        }
    };

    auto get_box = [&]() {
        while (1)
        {
            for (int i = 0; i < 10; i++)
            {
                if (box_queue.size() > 0)
                {
                    BaseBox box = box_queue.front();
                    box_queue.pop();
                }
            }
            std::cout << "get_box" << std::endl;
        }
    };

    std::thread t_add_box_1(add_box);
    t_add_box_1.detach();

    std::thread t_add_box_2(add_box);
    t_add_box_2.detach();

    std::thread t_add_box_3(add_box);
    t_add_box_3.detach();

    std::thread t_get_box(get_box);
    t_get_box.detach();
}

void test_deque_in_multi_thread()
{

#ifdef USE_THREAD_SAFE_CONTAINERS
#warning USE_THREAD_SAFE_CONTAINERS
    thread_safe::deque<BaseBox> box_deque;
#else
#warning NOT USE_THREAD_SAFE_CONTAINERS
    std::deque<BaseBox> box_deque;
#endif

    auto add_box = [&]() {
        while (1)
        {
            for (int i = 0; i < 10; i++)
            {
                BaseBox box;
                box_deque.push_front(box);
                box_deque.push_back(box);
                box_deque.emplace_back(box);
            }
            std::cout << "add_box" << std::endl;
        }
    };

    auto get_box = [&]() {
        while (1)
        {
            for (int i = 0; i < 10; i++)
            {
                BaseBox box;
                box = box_deque.front();
                box_deque.pop_front();

                box = box_deque.back();
                box_deque.pop_back();
            }
            std::cout << "get_box" << std::endl;
        }
    };

    std::thread t_add_box_1(add_box);
    t_add_box_1.detach();

    std::thread t_add_box_2(add_box);
    t_add_box_2.detach();

    std::thread t_add_box_3(add_box);
    t_add_box_3.detach();

    std::thread t_get_box(get_box);
    t_get_box.detach();
}

}  // namespace test